﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using LorraineSec.MessageLib.Messages;
using NetworkManagement;

namespace LorraineSec.MessageLib
{
    public sealed class LorraineSecMessageFactory : MessageFactory
    {
        /// <summary>
        /// An enumeration of every message type supported by this message factory.
        /// </summary>
        public enum MessageID
        {
            UNKNOWN,
            KEY_REQUEST,
            KEY_RESPONSE,
            SYMKEY_EXCHANGE,
            AUTH_REQUEST,
            AUTH_RESPONSE,
            COMPARTMENT_LIST_REQUEST,
            COMPARTMENT_LIST_RESPONSE,
            SUBSCRIBE_COMPARTMENT_REQUEST,
            SUBSCRIBE_COMPARTMENT_RESPONSE,
            DEVICE_LIST_REQUEST,
            DEVICE_LIST_RESPONSE,
            SUBSCRIBE_DEVICE_REQUEST,
            SUBSCRIBE_DEVICE_RESPONSE,
            ASSET_LIST_REQUEST,
            ASSET_LIST_RESPONSE,
            EDIT_ASSET,
            LOG_LIST_REQUEST,
            LOG_LIST_RESPONSE,
            CREATE_LOG,
            DEVICE_CALLBACK,
        }

        /// <summary>
        /// LorraineSec Message Factory Constructor.
        /// This object is thread safe.
        /// </summary>
        public LorraineSecMessageFactory()
        {
            /* Not having any instance variables allows this
             * object to be thread safe which is necessarry
             * for cases where one factory is being used for
             * multiple connections.
             */
        }

        /// <summary>
        /// Determines the message type and passed the byte data along to the
        /// appropriate message class for decoding
        /// </summary>
        /// <param name="bytes">The byte array representing a message.</param>
        /// <returns>A message object decoded based on the message format.</returns>
        public Message buildMessage(byte[] bytes)
        {
            Message msg = null;
            if (bytes != null)
            {
                switch ((MessageID)Bytes.getUInt16(bytes,Message.MSG_MSGID_OFFSET))
                {
                    case MessageID.AUTH_REQUEST:
                        return new AuthRequestMessage(bytes);
                    case MessageID.AUTH_RESPONSE:
                        return new AuthResponseMessage(bytes);
                    case MessageID.COMPARTMENT_LIST_REQUEST:
                        return new CompartmentListRequest(bytes);
                    case MessageID.COMPARTMENT_LIST_RESPONSE:
                        return new CompartmentListResponse(bytes);
                    case MessageID.KEY_REQUEST:
                        return new KeyRequestMessage(bytes);
                    case MessageID.KEY_RESPONSE:
                        return new KeyResponseMessage(bytes);
                    case MessageID.SYMKEY_EXCHANGE:
                        return new SymKeyExchangeMessage(bytes);
                    default:
                        break;
                }
            }
            return msg;
        }
    }
}
